package com.director.struts;

import com.director.core.DirectException;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.DefaultActionInvocation;
import com.opensymphony.xwork2.config.entities.ActionConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Author: Simone Ricciardi
 * Date: 2-lug-2010
 * Time: 16.39.07
 */
public class DirectActionInvocation extends DefaultActionInvocation {

   private static final Log LOG = LogFactory.getLog(DirectActionInvocation.class);

   public static final String DIRECT_ACTION_RESULT = "DIRECT_ACTION_RESULT";
   public static final String DIRECT_ACTION = "DIRECT_ACTION";
   public static final String DIRECT_METHOD = "DIRECT_METHOD";

   private Class directActionClass;
   private Method directActionMethod;
   private Object[] dataParams;

   public DirectActionInvocation(Map<String, Object> extraContext, Class directActionClass, Method directActionMethod, Object[] dataParams) {
      super(extraContext, true);
      this.directActionClass = directActionClass;
      this.directActionMethod = directActionMethod;
      this.dataParams = dataParams;
   }

   @Override
   protected String invokeAction(Object action, ActionConfig actionConfig) throws Exception {

      Object actionResult;
      try {
         actionResult = this.directActionMethod.invoke(action, this.dataParams);
      } catch (InvocationTargetException e) {
         Throwable methodException = e.getTargetException();
         String message = "Error invoking class: " + directActionClass.getName() + " method: " + directActionMethod.getName();
         LOG.error(message, methodException);
         throw new DirectException(message, methodException);
      } catch (IllegalAccessException e) {
         String message = "Error invoking class: " + directActionClass.getName() + " method: " + directActionMethod.getName();
         LOG.error(message, e);
         throw new DirectException(message, e);
      }

      this.getInvocationContext().put(DIRECT_ACTION_RESULT, actionResult);

      return Action.SUCCESS;
   }
}
